# Author: Mr.Xu
# @Time : 2019/12/1 22:54
import re
from django.core.cache import cache
from django.conf import settings
from rest_framework import serializers
from rest_framework_jwt.serializers import jwt_payload_handler, jwt_encode_handler

from . import models
from video import models as video_models


# 登陆序列化
class LoginModelSerializer(serializers.ModelSerializer):
    username = serializers.CharField(write_only=True)
    password = serializers.CharField(write_only=True)

    class Meta:
        model = models.User
        fields = ["username", "password"]

    def validate(self, attrs):
        # user = authenticate(**attrs)
        # 账号密码登录 => 多方式登录
        user = self._many_method_login(**attrs)

        # 签发token，并将user和token存放到序列化对象中
        payload = jwt_payload_handler(user)  # 使用jwt认证模块，根据当前用户得到载荷
        token = jwt_encode_handler(payload)  # 使用jwt认证模块，得到token

        self.user = user
        self.token = token

        return attrs

    # 多方式登录
    def _many_method_login(self, **attrs):
        username = attrs.get('username')
        password = attrs.get('password')
        if re.match(r'.*@.*', username):
            user = models.User.objects.filter(email=username).first()

        else:
            user = models.User.objects.filter(mobile=username).first()

        if not user:
            raise serializers.ValidationError({'user': '用户不存在'})

        if not user.check_password(password):
            raise serializers.ValidationError({'user': '账号或密码有误'})

        return user


# 手机登陆序列化
class MobileLoginModelSerializer(serializers.ModelSerializer):
    mobile = serializers.CharField(write_only=True)
    code = serializers.CharField(write_only=True)

    class Meta:
        model = models.User
        fields = ["mobile", "code"]

    def validate_code(self, value):
        try:
            int(value)
            return value
        except:
            raise serializers.ValidationError('验证码格式有误')

    def validate(self, attrs):
        # user = authenticate(**attrs)
        # 账号密码登录 => 多方式登录
        user = self._many_method_login(**attrs)

        # 签发token，并将user和token存放到序列化对象中
        payload = jwt_payload_handler(user)  # 使用jwt认证模块，根据当前用户得到载荷
        token = jwt_encode_handler(payload)  # 使用jwt认证模块，得到token

        self.user = user
        self.token = token

        return attrs

    # 多方式登录
    def _many_method_login(self, **attrs):
        mobile = attrs.get('mobile')
        code = attrs.pop("code")

        # 获取缓存数据库的验证码
        if cache.get(f"{settings.SMS_CACHE_KEY}{mobile}") != str(code):
            raise serializers.ValidationError({"code": "验证码错误"})

        # 为了保证验证码安全，验证码验证成功后，失效
        cache.set(f"{settings.SMS_CACHE_KEY}{mobile}", '0000', 0)

        user = models.User.objects.filter(mobile=mobile).first()

        if not user:
            raise serializers.ValidationError({'mobile': '用户不存在'})

        return user


# 注册序列化
class RegisterModelSerializer(serializers.ModelSerializer):
    mobile = serializers.CharField(min_length=11,max_length=11,write_only=True, required=True)
    re_password = serializers.CharField(write_only=True, required=True)
    code = serializers.IntegerField(write_only=True, required=True)

    class Meta:
        model = models.User
        fields = ["mobile", "password", "re_password", "code"]
        extra_kwargs = {
            "mobile":{
                "required":True,
                'min_length': 11,
                'max_length': 11,
                'error_messages': {
                    'min_length': '手机号格式有误'
                }
            },
            "password":{
                "required": True,
                'min_length': 3,
                'max_length': 18,
                'error_messages': {
                    'min_length': '密码格式有误'
                }
            }
        }

    def validate_mobile(self, value):
        obj = models.User.objects.filter(mobile=value).first()
        if obj:
            raise serializers.ValidationError("手机号已存在")
        return value

    def validate_code(self, value):
        try:
            int(value)
            return value
        except:
            raise serializers.ValidationError('验证码格式有误')

    def validate(self, attrs):
        mobile = attrs.get("mobile")
        password = attrs.get("password")
        re_password = attrs.pop("re_password")
        code = attrs.pop("code")

        # 校验密码
        if password != re_password:
            raise serializers.ValidationError({"password": "两次密码不一致"})

        # 获取缓存数据库的验证码
        if cache.get(f"{settings.SMS_CACHE_KEY}{mobile}") != str(code):
            raise serializers.ValidationError({"code": "验证码错误"})

        # 为了保证验证码安全，验证码验证成功后，失效
        cache.set(f"{settings.SMS_CACHE_KEY}{mobile}", '0000', 0)

        # 数据库存储
        attrs["username"] = mobile
        print(attrs)
        try:
            user_obj = models.User.objects.create_user(**attrs)
            # 添加用户详情表
            models.User_Detail.objects.create(user=user_obj,nick_name=user_obj.username)
        except:
            raise serializers.ValidationError({"user": "注册失败"})

        # 签发token，并将user和token存放到序列化对象中
        payload = jwt_payload_handler(user_obj)  # 使用jwt认证模块，根据当前用户得到载荷
        token = jwt_encode_handler(payload)  # 使用jwt认证模块，得到token

        self.user = user_obj
        self.token = token

        return attrs


class UserDetailModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.User_Detail
        fields = ["get_created_time","get_updated_time","nick_name","birthday","gender_name","desc","vip_type","exp_time"]


class UserVipTypeModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.User
        fields = ["get_vip_type"]


class UserVideoRecordModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = video_models.Record
        fields = ["get_updated_time","play_time","section_info","video_id"]